package com.moli.iov.down.command.design.command.reshandler.impl;

import com.moli.iov.down.command.SendCommandService;
import com.moli.iov.down.command.codec.decode.bean.SettingBean;
import com.moli.iov.down.command.codec.decode.bean.extend.SettingExtendBean;
import com.moli.iov.down.command.codec.decode.decoders.SettingDecoder;
import com.moli.iov.down.command.codec.utils.Protocol;
import com.moli.iov.down.command.design.command.reshandler.ResponseHandlerCommand;
import com.moli.iov.down.command.mq.SendCache;
import com.moli.iov.down.enums.OperatorResultEnum;
import com.moli.iov.down.enums.command.CommandEnum;
import com.moli.iov.down.enums.command.SettingResponseResultEnum;
import com.moli.iov.down.enums.command.TerminalControlEnum;
import com.moli.iov.down.enums.command.TerminalSettingEnum;
import com.moli.iov.down.enums.command.extend.ExtendRestartEnum;
import com.moli.iov.down.model.dto.remoting.CommandDto;
import com.moli.iov.down.model.dto.remoting.CommandResDto;
import com.moli.iov.down.model.po.VehicleCommand;
import com.moli.iov.down.service.IVehicleCommandService;
import com.moli.iov.util.ByteArrayUtil;
import com.moli.iov.util.SpringContextUtils;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.task.TaskExecutor;

/**
 * <p>
 * 终端参数设置结果应答
 * </p>
 *
 * @author: zql
 * @Date: 2018/12/29 17:43
 */
public class TerminalParameterSettingCommand implements ResponseHandlerCommand {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    private SendCache sendCache = SpringContextUtils.getBean("sendCache");

    private IVehicleCommandService vehicleCommandService =
        SpringContextUtils.getBean("vehicleCommandService");

    private SendCommandService sendCommandService = SpringContextUtils.getBean("sendCommandService");

    private TaskExecutor taskExecutor = SpringContextUtils.getBean("taskExecutor");


    @Override
    public void execute(Protocol protocol) {
        String vin = protocol.getVin();
        byte command = protocol.getCommandTag();

        SettingDecoder settingDecoder = SpringContextUtils.getBean("settingDecoder");
        SettingBean decode = settingDecoder.decode(protocol.getData());
        decode.setVin(vin);
        String serialNumber = String.valueOf(decode.getSerialNumber());

        paramenterSettingHandle(decode);

        sendCache.updateResResult(vin, command, serialNumber);
    }

    /**
     *
     * 参数设置响应 handle
     *
     * @param decode
     */
    public void paramenterSettingHandle(SettingBean decode){

        logger.info("[上行响应报文] [参数设置响应] remoteControlResBean：{}", decode);

        VehicleCommand vehicleCommand = new VehicleCommand();
        vehicleCommand.setVin(decode.getVin());
        vehicleCommand.setResponseNo(Long.parseLong(String.valueOf(decode.getSerialNumber())));

        CommandResDto commandResDto = assemblyParameterSettingResDto(decode);

        if(commandResDto.isBluetoothPwd()){
            //设置蓝牙秘钥响应
            return;
        }

        generalBiz(decode, commandResDto, vehicleCommand);
    }

    /**
     * 普通参数设置结果处理
     * @param decode
     * @param commandResDto
     * @param vehicleCommand
     */
    public void generalBiz(SettingBean decode,
                                CommandResDto commandResDto,
                                VehicleCommand vehicleCommand){
        boolean isIpOrPort = commandResDto.getIsIpOrPort();
        int resSesult = commandResDto.getResSesult();

        if(isIpOrPort &&
                OperatorResultEnum.SUCCESS.getFlag() == resSesult){
            //修改ip 或端口 则立即重启终端
            this.sendRestart(decode.getVin());
            logger.info("[上行响应报文] [参数设置响应] 修改ip 或 端口  立即重启终端");
        }

        vehicleCommand.setResult(resSesult);
        vehicleCommand.setResultMemo(commandResDto.getFailMsg());
        vehicleCommand.setResponseTime(new Date());
        vehicleCommandService.updateResult(vehicleCommand);
    }

    /**
     * 组装result信息
     * @param decode
     * @return
     */
    private CommandResDto assemblyParameterSettingResDto(SettingBean decode){

        CommandResDto commandResDto = new CommandResDto();
        commandResDto.setIsIpOrPort(false);
        StringBuilder failMsg = new StringBuilder();
        int resSesult = OperatorResultEnum.SUCCESS.getFlag();

        for(SettingExtendBean settingExtendBean : decode.getSettingExtendBeans()){
            if(settingExtendBean.getResult() != SettingResponseResultEnum.SUCCESS.getFlag()){
                resSesult = OperatorResultEnum.FAIL.getFlag();
                if(failMsg.length() > 0){
                    failMsg.append(",");
                }

                failMsg.append(TerminalSettingEnum.getMsg(settingExtendBean.getParamId()) +
                        ":" +
                        SettingResponseResultEnum.getMsg(settingExtendBean.getResult()));
            }

            if(TerminalSettingEnum.IP.getFlag().equals(settingExtendBean.getParamId()) ||
                    TerminalSettingEnum.PORT.getFlag().equals(settingExtendBean.getParamId())){
                commandResDto.setIsIpOrPort(true);
            }

            if(TerminalSettingEnum.BLUETOOTH_PWD.getFlag().equals(settingExtendBean.getParamId())){
                commandResDto.setBluetoothPwd(true);
                commandResDto.setBluetoothPwdSuccess(SettingResponseResultEnum.SUCCESS.getFlag() == settingExtendBean.getResult());
                String result = ByteArrayUtil.toHexString(settingExtendBean.getResult());
                logger.info("蓝牙处理结果：{} vin:{}", result, decode.getVin());
            }
        }
        commandResDto.setResSesult(resSesult);
        commandResDto.setFailMsg(failMsg.toString());
        return commandResDto;
    }

    /**
     * 重启终端
     * @param vin
     */
    public void sendRestart(String vin) {
        try{
            taskExecutor.execute(() -> {

                CommandDto commandDto = new CommandDto();
                commandDto.setVin(vin);
                commandDto.setCommand(CommandEnum.TERMINAL_CONTROL.getFlag());
                commandDto.setControlCommand(TerminalControlEnum.RESTART.getFlag());
                commandDto.setControlContent(ExtendRestartEnum.ENABLE.getFlag());
                commandDto.setIsRetry(true);
                sendCommandService.sendCommand(commandDto);
            });
        }catch(Exception e){
            logger.error("重启终端 异常", e);
        }
    }
}
